package com.jiangjiang.eshop.schedule.service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jiangjiang.eshop.order.dto.OrderItemDTO;
import com.jiangjiang.eshop.schedule.domain.ScheduleGoodsAllocationStockDetail;
import com.jiangjiang.eshop.schedule.dto.SaleDeliveryScheduleResult;
import com.jiangjiang.eshop.schedule.dto.ScheduleOrderPickingItemDTO;
import com.jiangjiang.eshop.schedule.dto.ScheduleOrderSendOutDetailDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @ClassName SaleDeliveryScheduler
 * @Description TODO
 * @Author jhw
 * @Date 2021/7/24 15:57
 * @Version 1.0
 **/
@Component
public class SaleDeliveryScheduler {

    @Autowired
    private ScheduleGoodsAllocationStockDetailService scheduleGoodsAllocationStockDetailService;
    @Autowired
    private ScheduleOrderPickingItemService scheduleOrderPickingItemService;
    @Autowired
    private ScheduleOrderSendOutDetailService scheduleOrderSendOutDetailService;

    /**
     * 调度销售出库
     *
     * @param orderItem 订单条目
     * @return 调度结果
     * @throws Exception
     */
    public SaleDeliveryScheduleResult schedule(OrderItemDTO orderItem) {
        // 查询货位库存明细
        List<ScheduleGoodsAllocationStockDetail> stockDetails = scheduleGoodsAllocationStockDetailService.listByGoodsSkuId(orderItem.getGoodsId());
        //销售数量
        Long purchaseQuantity = orderItem.getPurchaseQuantity();
        //剩余代发货数量
        Long remainingSendOutQuantity = purchaseQuantity;
        // 拣货条目
        Map<Long, ScheduleOrderPickingItemDTO> pickingItems = Maps.newHashMap();
        // 发货明细
        List<ScheduleOrderSendOutDetailDTO> sendOutDetails = new ArrayList<>();
        for (ScheduleGoodsAllocationStockDetail stockDetail : stockDetails) {
            if (stockDetail.getCurrentStockQuantity() >= remainingSendOutQuantity) {
                updatePickingItem(stockDetail.getGoodsAllocationId(), orderItem.getGoodsSkuId(), remainingSendOutQuantity, pickingItems);
                updateSendOutDetail(sendOutDetails, stockDetail.getId(), remainingSendOutQuantity);
                break;
            }

            updatePickingItem(stockDetail.getGoodsAllocationId(), orderItem.getGoodsSkuId(), stockDetail.getCurrentStockQuantity(), pickingItems);
            updateSendOutDetail(sendOutDetails, stockDetail.getId(), stockDetail.getCurrentStockQuantity());
            // 剩余发货库存扣减
            remainingSendOutQuantity -= stockDetail.getCurrentStockQuantity();
        }

        return SaleDeliveryScheduleResult.builder().orderItem(orderItem)
                .sendOutDetails(sendOutDetails)
                .pickingItems(Lists.newArrayList(pickingItems.values()))
                .build();

    }

    /**
     * 更新发货明细集合
     *
     * @param sendOutDetails          发货明细集合
     * @param allocationStockDetailId 货位明细库存 id
     * @param sendOutCount            发货数量
     */
    private void updateSendOutDetail(List<ScheduleOrderSendOutDetailDTO> sendOutDetails, Long allocationStockDetailId, Long sendOutCount) {
        ScheduleOrderSendOutDetailDTO sendOutDetailDTO = new ScheduleOrderSendOutDetailDTO();
        sendOutDetailDTO.setGoodsAllocationStockDetailId(allocationStockDetailId);
        sendOutDetailDTO.setSendOutCount(sendOutCount);
        sendOutDetails.add(sendOutDetailDTO);
    }

    /**
     * 更新拣货条目
     *
     * @param goodsAllocationId 货位编号
     * @param goodsSkuId        商品 sku id
     * @param pickingCount      拣货数量
     * @param pickingItems      拣货条目map
     */
    private void updatePickingItem(Long goodsAllocationId, Long goodsSkuId, Long pickingCount,
                                   Map<Long, ScheduleOrderPickingItemDTO> pickingItems) {
        ScheduleOrderPickingItemDTO itemDTO = pickingItems.get(goodsAllocationId);
        if (Objects.isNull(itemDTO)) {
            itemDTO = new ScheduleOrderPickingItemDTO();
            itemDTO.setGoodsAllocationId(goodsAllocationId);
            itemDTO.setGoodsSkuId(goodsSkuId);
            itemDTO.setPickingCount(pickingCount);
            pickingItems.put(goodsAllocationId, itemDTO);
        } else {
            itemDTO.setPickingCount(itemDTO.getPickingCount() + pickingCount);
        }


    }

    /**
     * 获取订单条目的调度结果
     *
     * @param orderItemDTO 订单条目
     * @return
     */
    public SaleDeliveryScheduleResult getScheduleResult(OrderItemDTO orderItemDTO) {
        List<ScheduleOrderPickingItemDTO> pickingItems = scheduleOrderPickingItemService
                .listByOrderItemId(orderItemDTO.getOrderInfoId(), orderItemDTO.getId());

        List<ScheduleOrderSendOutDetailDTO> sendOutDetails =  scheduleOrderSendOutDetailService
                .listByOrderItemId(orderItemDTO.getOrderInfoId(), orderItemDTO.getId());


        return SaleDeliveryScheduleResult.builder()
                .orderItem(orderItemDTO)
                .pickingItems(pickingItems)
                .sendOutDetails(sendOutDetails)
                .build();
    }

}
